#!/usr/bin/python
#coding:utf-8
from mininet.topo import Topo
from mininet.net import Mininet
from mininet.node import CPULimitedHost
from mininet.link import TCLink
from mininet.util import dumpNodeConnections
from mininet.log import setLogLevel
from mininet.cli import CLI

class FatTreeTopo(Topo):
	# 胖树
	def build(self):
		L1 = 2
		L2 = L1 * 2
		L3 = L2
		c = []
		a = []
		e = []

		# add core ovs
		for i in range(L1):
			sw = self.addSwitch('c{}'.format(i + 1))
			c.append(sw)

		# add aggregation ovs
		for i in range(L2):
			sw = self.addSwitch('a{}'.format(L1 + i + 1))
			a.append(sw)

		# add edge ovs
		for i in range(L3):
			sw = self.addSwitch('e{}'.format(L1 + L2 + i + 1))
			e.append(sw)

		# add links between core and aggregation ovs
		for i in range(L1):
			sw1 = c[i]
			for sw2 in a[i/2::L1/2]:
				if sw1 == 'c1' and sw2 == 'a4': # link 2
					continue
				if sw1 == 'c1' and sw2 == 'a6': # link 4
					continue
				if sw1 == 'c2' and sw2 == 'a3': # link 5
					continue
				if sw1 == 'c2' and sw2 == 'a5': # link 7
					continue
				self.addLink(sw2, sw1)

		# add links between aggregation and edge ovs
		for i in range(0, L2, 2):
			for sw1 in a[i:i+2]:
				for sw2 in e[i:i+2]:
					if sw1 == 'a4' and sw2 == 'e8': # link 12
						continue
					if sw1 == 'a5' and sw2 == 'e10': # link 14
						continue
					self.addLink(sw2, sw1)

		#add hosts and its links with edge ovs
		count = 1
		for sw1 in e[::2]:
			host = self.addHost('h{}'.format(count))
			self.addLink(sw1, host)
			count += 1

topos = {'mytopo': (lambda: FatTreeTopo())}
